/* 
* Copyright (C) 2005, 2006 Liu Di <liudidi@gmail.com> 
*
* Copyright (C) 2007 Wei Lian <lianwei3@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "header.h"
#include "channel.h"
#include "mainwindow.h"
#include "mylistitem.h"
#include "config.h"
#include "mylabel.h"
#include "menubar.h"
#include "pageplay.h"
#include "record.h"
#include "tabwidget.h"

Channel::Channel (QWidget * parent, const char *name, WFlags f):
QListView (parent, name, f),
mainwindow (static_cast < MainWindow * >(parent))
{
   //listview
   addColumn (tr ("Name"));
/*  addColumn(tr("Status"));
    addColumn(tr("Type"));
    addColumn(tr("Kbps"));
    addColumn(tr("Users"));
    addColumn(tr("Vists"));
    addColumn(tr("QualityS"));
    addColumn(tr("QualityC"));
    addColumn(tr("StarFrom"));
    addColumn(tr("URL"));
    addColumn(tr("Description"));*/
   setRootIsDecorated (TRUE);

   connect (this, SIGNAL (doubleClicked (QListViewItem *)), this,
	    SLOT (onListItemClicked (QListViewItem *)));
   connect (this, SIGNAL (returnPressed (QListViewItem *)), this,
	    SLOT (onListItemClicked (QListViewItem *)));
   connect (this,
	    SIGNAL (rightButtonClicked
		    (QListViewItem *, const QPoint &, int)), this,
	    SLOT (onRightButtonClicked
		  (QListViewItem *, const QPoint &, int)));
   connect (this, SIGNAL (onItem (QListViewItem *)), this,
	    SLOT (onMouseMoved (QListViewItem *)));

   //popup
   popup = new MyLabel (this);

   bufchannel = new QBuffer ();
   ///open bufchannel
   if (!bufchannel->open (IO_ReadWrite)) {
      perror ("cannot create the buffer");
      return;
   }
   ////
   http = new QHttp (this);
   ///signal progress for http
   connect (http, SIGNAL (dataReadProgress (int, int)), this,
	    SLOT (onDataReadProgress (int, int)));

}


Channel::~Channel ()
{
   ///close bufchannel
   bufchannel->close ();
   delete bufchannel;
}


///-------------------------------------------------------
void
Channel::onListItemClicked (QListViewItem *)
{
   if (static_cast < MyHBox * >(mainwindow->tabwidget->currentPage ())
       ->pagetype == "play")
      static_cast < PagePlay * >(mainwindow->tabwidget->currentPage ())
	 ->onButtonLaunchClicked ();
   else
      static_cast < Record * >(mainwindow->tabwidget->currentPage ())
	 ->buttonrecord->setOn (true);
}


void
Channel::onDataReadProgress (int done, int)
{
   ///use button channel forground color to illuminate progress
   int period = 119625;
   int num = (done / period) % 2 ?
      255 - (256 * done / period) % 256 : (256 * done / period) % 256;
   ///
   mainwindow->buttonchannel->setPaletteForegroundColor (QColor (0, num, 0));
}


void
Channel::onButtonChannelToggled (bool t)
{
   if (t) {
      connect (http, SIGNAL (done (bool)), this, SLOT (httpDone (bool)));
      ///reset buffer pointer to 0
      bufchannel->reset ();
      ///
      QString str = mainwindow->vboxconfig->editchannelurl->text ();

      http->setHost (str.section ("/", 2, 2));	//"www.sopcast.org");
      http->get ("/" + str.section ("/", 3), bufchannel);	//"/channel/index.php", bufchannel);
   }
   else {
      disconnect (http, SIGNAL (done (bool)), this, SLOT (httpDone (bool)));
      http->abort ();
      ///reset color for button channel
      mainwindow->buttonchannel->setPaletteForegroundColor (Qt::black);
   }
}


void
Channel::httpDone (bool error)
{
   ///reset button channel and reset its color
   mainwindow->buttonchannel->setOn (false);

   if (error) {
      fprintf (stderr, "Network is poor, fail to download channel list\n");
      ///restart fetching channel
      mainwindow->buttonchannel->setOn (true);
      return;
   }

   ///toggle channel sorting
   toggleChannelSort ();
   ///

   ///reset buffer pointer to 0
   bufchannel->reset ();
   QDomDocument doc ("mydocument");
   doc.setContent (bufchannel);

   ////
   QDomElement root = doc.documentElement ();
   QDomNode node = root.firstChild ();

   QDomNode channelnode, namenode;
   QListViewItem *groupitem = 0;
   MyListItem *item = 0;

   updateOpenState ();
   clear ();

   for (int i = 0; i < N_COLUMNS; i++)
      Max[i] = 1;
   static const char node_name[][20] =
      { "name", "status", "stream_type", "kbps", "user_count",
      "visit_count", "qs", "qc", "start_from", "sop_address",
      "description"
   };
   ///group
   while (!node.isNull ()) {
      if (node.isElement () && node.nodeName () == "group") {
	 groupitem = new QListViewItem (this, groupitem);
	 groupitem->setText (0, node.firstChild ().toText ().nodeValue ());
	 ///channel
	 channelnode = node.toElement ().firstChild ();
	 while (!channelnode.isNull ()) {
	    if (channelnode.isElement ()
		&& channelnode.nodeName () == "channel") {
	       ///element
	       item = new MyListItem (groupitem, item);
	       namenode = channelnode.toElement ().firstChild ();
	       while (!namenode.isNull ()) {
		  for (int i = 0; i < N_COLUMNS; i++) {
		     if (namenode.nodeName () == "sop_address")
			item->setText (URL_COLUMN,
				       namenode.firstChild ().
				       toElement ().firstChild ().
				       toText ().nodeValue ());
		     else if (namenode.nodeName () == node_name[i])
			item->setText (i,
				       namenode.firstChild ().
				       toText ().nodeValue ());
		  }
		  namenode = namenode.nextSibling ();
	       }

	       ///filtering out channel
	       if (channelnode.toElement ().attribute ("type").toInt () == 1)
		  item->state |= 2;
	       ///disable null channel
	       else if (item->text (URL_COLUMN) == "null")
		  item->state |= 1;
	       else {
		  static const int num[] =
		     { USER_COLUMN, VISIT_COLUMN, QS_COLUMN,
		     QC_COLUMN, KBPS_COLUMN
		  };
		  for (int i = 0; i < 5; i++)
		     Max[num[i]] =
			item->text (num[i]).toInt () >
			Max[num[i]] ? item->text (num[i]).
			toInt () : Max[num[i]];

	       }
	    }
	    channelnode = channelnode.nextSibling ();
	 }
	 ///group
      }
      node = node.nextSibling ();
   }

   ///toggle null channel
   toggleNullChannel ();

   ////switch color
   switchChannelColor (mainwindow->menubar->color_column);

   ///set open
   QListViewItem *group = firstChild ();
   int count = 0;
   while (group) {
      if (stateopen[count++] == 1)
	 group->setOpen (TRUE);
      group = group->nextSibling ();
   }

}


void
Channel::onRightButtonClicked (QListViewItem * item, const QPoint & pos, int)
{
   if (item)
      if (item->depth () == 1) {
	 popup->move (pos);
	 popup->
	    setText
	    ("<table border=0 cellspacing=0 cellpadding=0><tr><td>" +
	     item->text (NAME_COLUMN) +
	     "</td></tr></table><hr>"
	     "<table border=0 cellspacing=0 cellpadding=0>"
	     "<tr><td>Users: " + item->text (USER_COLUMN) +
	     "</td><td>Visitors: " + item->text (VISIT_COLUMN) +
	     "</td></tr>" "<tr><td>QualityC: " +
	     item->text (QC_COLUMN) + "</td><td>QualityS: " +
	     item->text (6) + "</td></tr>" "<tr><td>MediaType: " +
	     item->text (STREAM_COLUMN) + "</td><td>KBps: " +
	     item->text (KBPS_COLUMN) +
	     "</td></tr>" "<tr><td>StartFrom: " +
	     item->text (START_COLUMN) + "</td></tr></table><br>" +
	     item->text (DESCRIPTION_COLUMN));
	 popup->adjustSize ();
	 popup->show ();
      }
}


void
Channel::onMouseMoved (QListViewItem *)
{
   popup->hide ();
}


void
Channel::mouseMoveEvent (QMouseEvent * e)
{
   QPoint p (e->pos ());
   QRect pr (rect ());
   pr.setWidth (pr.width () -
		verticalScrollBar ()->width () *
		verticalScrollBar ()->isVisible ());
   pr.setHeight (pr.height () -
		 horizontalScrollBar ()->height () *
		 horizontalScrollBar ()->isVisible ());
   if (!pr.contains (p)) {
      popup->hide ();
   }
}


void
Channel::toggleChannelSort ()
{
   if (!mainwindow->menubar->menu_config->isItemChecked (CHANNEL_SORT))
      setSortColumn (-1);
   else
      setSortColumn (0);
}


void
Channel::toggleNullChannel ()
{
   bool t = mainwindow->menubar->menu_config->isItemChecked (NULL_CHANNEL);

   QListViewItem *group = firstChild ();
   while (group) {
      QListViewItem *child = group->firstChild ();
      int count = 0;
      while (child) {
	 switch (((MyListItem *) child)->state) {
	 case 0:
	 case 2:
	    count++;
	    break;
	 case 1:
	    child->setEnabled (FALSE);
	    if (t) {
	       child->setVisible (TRUE);
	       count++;
	    }
	    else
	       child->setVisible (FALSE);
	    break;
	 case 3:
	    child->setEnabled (FALSE);
	    child->setVisible (FALSE);
	 }
	 child = child->nextSibling ();
      }
      if (count == 0)
	 group->setVisible (FALSE);
      else
	 group->setVisible (TRUE);
      ///iterate to next group
      group = group->nextSibling ();
   }
}


void
Channel::switchChannelColor (int column)
{
   QListViewItem *group = firstChild ();
   while (group) {
      QListViewItem *child = group->firstChild ();
      while (child) {
	 if (child->isEnabled ()) {
	    int level =
	       int (child->text (column).toInt () * (255. / Max[column]));

	    level = level < 0 ? 0 : level;
	    level = level > 255 ? 255 : level;

	    ((MyListItem *) child)->fcolor.setHsv (255 - level, 255, 125);
	    child->repaint ();
	 }
	 child = child->nextSibling ();
      }
      group = group->nextSibling ();
   }
}


void
Channel::updateOpenState ()
{
   QListViewItem *myChild = firstChild ();
   int count = 0;
   while (myChild) {
      if (myChild->isOpen ())
	 stateopen[count++] = 1;
      else
	 stateopen[count++] = 0;

      myChild = myChild->nextSibling ();
   }
}


bool
   Channel::SopMatch (QString & channelurl, QString & channelname,
		      QString & channeltype)
{
   channelname = "sop";
   channeltype = "wmv";

   int startpos =
      channelurl.find (mainwindow->vboxconfig->editchannelheader->text ());
   ///not a valid URL
   if (startpos == -1)
      return false;
   ///normalize URL
   channelurl = channelurl.mid (startpos);
   channelurl = channelurl.mid (0, channelurl.find (" "));

   ///traversal the channel list to find the 1st match
   QListViewItem *item, *childitem;
   item = firstChild ();
   while (item) {
      childitem = item->firstChild ();
      while (childitem) {
	 if (channelurl == childitem->text (URL_COLUMN)) {
	    channelname = childitem->text (NAME_COLUMN);
	    channeltype = childitem->text (STREAM_COLUMN);
	    goto FINISHED;
	 }
	 childitem = childitem->nextSibling ();
      }
      item = item->nextSibling ();
   }
 FINISHED:

   return true;
}
